<?php

namespace App\Repositories;

use App\Enums\RedisKeyEnum;
use App\Enums\RoomEnum;
use App\Enums\CrossRoomPkEnum;
use App\Enums\CurlReportUrlEnum;
use App\Jobs\QiPao\GeneralRoomJob;
use App\Exceptions\BasicException;
use App\Jobs\RongCloud\RoomPushJob;
use App\Services\Tools\CurlService;
use App\Services\Tools\CommonService;
use App\Services\Tools\PushService;
use App\Services\Tools\RedisService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class RoomRepository
{

    public function roomLockTimeStatistic($params)
    {
        $typeId = empty($params['type_id']) ? 0 : $params['type_id'];
        $userCode = empty($params['user_code']) ? 0 : $params['user_code'];
        $nickname = empty($params['nickname']) ? 0 : $params['nickname'];
        $roomId = empty($params['room_id']) ? 0 : $params['room_id'];
        $roomName = empty($params['room_name']) ? '' : $params['room_name'];
        $startTime = isset($params['start_time']) ? strtotime($params['start_time']) : 0;
        $endTime = isset($params['end_time']) ? strtotime($params['end_time'] . " 23:59:59") : 0;
        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $day = 0;
        $whereArr = [];
        if ($startTime) {
            $whereArr[] = ["t1.lock_time", ">=", $startTime];
        }

        if ($endTime) {
            $whereArr[] = ["t1.lock_time", "<=", $endTime];
        }

        if ($startTime && $endTime) {
            $day = ($endTime - $startTime) / 86400;
        }

        if ($roomId) {
            $whereArr[] = ["t2.room_id", "=", $roomId];
        }

        if ($userCode) {
            $whereArr[] = ["t3.user_code", "=", $userCode];
        }

        if ($nickname) {
            $whereArr[] = ["t3.nickname", "like", "%" . $nickname . "%"];
        }

        if ($roomName) {
            $whereArr[] = ["t2.room_name", "like", "%" . $roomName . "%"];
        }

        $whereFunc = function ($query) use ($typeId) {
            if ($typeId) {
                $query->where("t2.type_id", $typeId)
                    ->orWhere("t2.sys_type_id", $typeId);
            }
        };

        $lockLogModel = app('model_room_lock_log');
        $userRoomModel = app("model_user_room");
        $userDataModel = app("model_user_data");

        $subQuery = app('model_room_lock_log')
            ->from($lockLogModel->getTable() . " as t1")
            ->select(
                DB::raw("sum(t1.unlock_time - t1.lock_time) as total_lock_time"),
                "t2.room_name",
                "t2.room_id",
                "t3.nickname",
                "t3.head_picture",
                "t3.user_code"
            )
            ->join(DB::raw($userRoomModel->getTable() . " as t2"), "t1.room_id", "=", "t2.id")
            ->join(DB::raw($userDataModel->getTable() . " as t3"), "t2.user_id", "=", "t3.user_id")
            ->groupBy('t1.room_id')
            ->where($whereArr)
            ->where($whereFunc);

        $result = DB::connection('mysql')->table(DB::raw("({$subQuery->toSql()}) as t4"))
            ->orderBy('t4.total_lock_time', 'desc')
            ->orderBy('t4.room_id', 'desc')
            ->mergeBindings($subQuery->getQuery())
            ->paginate($perPage, ['*'], '', $page);

        foreach ($result as $item) {
            if ($day > 0) {
                if ($item->total_lock_time <= 0) {
                    $item->lock_time_avg = '-';
                } else {
                    $avg_day = CommonService::time_format(round($item->total_lock_time / $day));
                    $item->lock_time_avg = $avg_day;
                }
            } else {
                $item->lock_time_avg = '-';
            }

            if ($item->total_lock_time >= 0) {
                $item->total_lock_time = CommonService::time_format($item->total_lock_time);
            } else {
                $item->total_lock_time = "锁房中";
            }
        }

        return $result;
    }

    public function statistic($params)
    {
        $labelId = $params['label_id'];
        $startTime = isset($params['start_time']) ? strtotime($params['start_time']) : 0;
        $endTime = isset($params['end_time']) ? strtotime($params['end_time'] . " 23:59:59") : 0;
        $limit = 10;

        $giveGiftModel = app('model_give_gift');
        $userRoomModel = app("model_user_room");
        $userModel = app("model_user");

        $subQuery = app('model_give_gift')
            ->from($giveGiftModel->getTable() . " as t1")
            ->select(
                DB::raw("sum(t1.total_price) as total"),
                "t2.room_name",
                "t2.room_id"
            )
            ->join(DB::raw($userRoomModel->getTable() . " as t2"), "t1.room_id", "=", "t2.id")
            ->groupBy('t1.room_id')
            ->where(function ($query) use ($startTime, $endTime, $labelId) {
                if ($startTime) {
                    $query->whereRaw(DB::raw("t1.add_time >= {$startTime}"));
                }
                if ($endTime) {
                    $query->whereRaw(DB::raw("t1.add_time <= {$endTime}"));
                }
                if ($labelId) {
                    $query->whereRaw(DB::raw("t2.label_id = {$labelId}"));
                }
            });

        $incomeList = DB::connection('mysql')->table(DB::raw("({$subQuery->toSql()}) as t4"))
            ->orderBy('t4.total', 'desc')
            ->limit($limit)
            ->get();

        foreach ($incomeList as $item) {
            $item->date = $params['start_time'] . "~" . $params['end_time'];
        }

        $newSubQuery = app('model_give_gift')
            ->from($giveGiftModel->getTable() . " as t1")
            ->select(
                DB::raw("count(distinct t1.user_id) as total"),
                "t2.room_name",
                "t2.room_id"
            )
            ->join(DB::raw($userRoomModel->getTable() . " as t2"), "t1.room_id", "=", "t2.id")
            ->join(DB::raw($userModel->getTable() . " as t3"), "t1.user_id", "=", "t3.user_id")
            ->groupBy('t1.room_id')
            ->where(function ($query) use ($startTime, $endTime, $labelId) {
                if ($startTime) {
                    $query->whereRaw(DB::raw("t1.add_time >= {$startTime}"));
                    $query->whereRaw(DB::raw("t3.register_time >= {$startTime}"));
                }
                if ($endTime) {
                    $query->whereRaw(DB::raw("t1.add_time <= {$endTime}"));
                    $query->whereRaw(DB::raw("t3.register_time <= {$endTime}"));
                }
                if ($labelId) {
                    $query->whereRaw(DB::raw("t2.label_id = {$labelId}"));
                }
            });

        $newList = DB::connection('mysql')->table(DB::raw("({$newSubQuery->toSql()}) as t4"))
            ->orderBy('t4.total', 'desc')
            ->limit($limit)
            ->get();

        foreach ($newList as $item) {
            $item->date = $params['start_time'] . "~" . $params['end_time'];
        }

        return [
            "income_list" => $incomeList,
            "new_list"    => $newList,
        ];
    }

    /**
     * 新增
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addBackgroundImage($param)
    {
        $addConfig = app('model_room_background')->create($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 一键新增背景图价格
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addBackgroundPrice($param)
    {
        $add = app('model_room_background_product_price')->insert($param);
        if ($add) return $add;
        throw new BasicException(93107);
    }

    /**
     * 删除产品价格
     * @param $param
     */
    public function delBackgroundPrice($param)
    {
        app('model_room_background_product_price')->where('room_background_id', $param)->delete();
    }

    /**
     * 删除
     */
    public function delBackgroundImage($idArr = [])
    {
        $res = app('model_room_background')->whereIn("id", $idArr)->delete();

        if ($res) {
            return $res;
        }
        throw new BasicException(93044);
    }

    /**
     * 修改
     */
    public function saveBackgroundImage($where, $param)
    {
        $saveConfig = app('model_room_background')->where($where)->update($param);

        if ($saveConfig !== false) {
            return true;
        }
        throw new BasicException(93047);
    }

    /**
     * 获取背景图详情
     * @param $where array 条件
     * @return bool
     * @throws BasicException
     */
    public function getBackgroundImageInfo($where)
    {
        $info = app('model_room_background')->where($where)->first();

        if ($info !== false) {
            return $info;
        }
        throw new BasicException(93047);
    }

    /**
     * 赠送背景墙
     * @param $room_background_id int 背景图id
     * @param $user_id int 使用人用户id
     * @param int $use_days 使用天数
     * @return bool
     * @throws BasicException
     */
    public function give($room_background_id, $user_id, $use_days = 0)
    {
        if ($room_background_id <= 0) {
            throw new BasicException(10001, "请选择商品!");
        }
        if ($user_id <= 0) {
            throw new BasicException(10001, "请选择用户!");
        }
        $product = app("model_room_background")->where("id", $room_background_id)->first();
        if (!$product) {
            throw new BasicException(10001, "背景图不存在!");
        }
        $price = app("model_room_background_product_price")->where([
            ['room_background_id', '=', $room_background_id],
            ['day', '=', $use_days]
        ])->first();

        $user = app("repo_user")->getUserInfo($user_id);
        if (!$user) {
            throw new BasicException(10001, "用户不存在!");
        }

        $detail = app("model_room_background_buy_log")->where([
            ['room_background_id', "=", $room_background_id],
            ['use_user_id', "=", $user_id]
        ])->first();
        if ($detail) {
            if ($detail['overdue_time'] < time()) {
                $update_data = [
                    'overdue_time' => time() + $use_days * 86400,
                    'day'          => $use_days,
                ];
            } else {
                $update_data = [
                    'overdue_time' => $detail['overdue_time'] + $use_days * 86400,
                    'day'          => $use_days,
                ];
            }
            $re = app("model_room_background_buy_log")->where([['id', "=", $detail['id']]])->update($update_data);
        } else {
            $expired_time = -1;
            if ($use_days > 0) {
                $expired_time = time() + $use_days * 86400;
            }
            $re = app("model_room_background_buy_log")->create([
                'buy_user_id'          => app("request")->admin_id,
                'buy_user_name'        => app("request")->admin_id . '管理员',
                'use_user_id'          => $user_id,
                'use_user_name'        => $user['user_data']['nickname'],
                'room_background_id'   => $room_background_id,
                'room_background_name' => $product->name,
                'add_time'             => time(),
                'price'                => floatval($price['price'] ?? 0),
                'day'                  => $use_days,
                'picture'              => $product->picture,
                'effect_picture'       => $product->effect_picture,
                'overdue_time'         => $expired_time,
                'renew_number'         => 0
            ]);
        }
        if (!$re) {
            throw new BasicException(10001, "赠送失败，请重试!");
        }
        // 后台购买记录
        app("model_room_background_buy_log_view")->create([
            'buy_user_id'          => app("request")->admin_id,
            'buy_user_name'        => app("request")->admin_id . '管理员',
            'use_user_id'          => $user_id,
            'use_user_name'        => $user['user_data']['nickname'],
            'room_background_id'   => $room_background_id,
            'room_background_name' => $product->name,
            'add_time'             => time(),
            'price'                => floatval($price['price'] ?? 0),
            'day'                  => $use_days,
            'picture'              => $product->picture,
            'effect_picture'       => $product->effect_picture,
        ]);

        return true;
    }

    /**
     * 理员后台查询配置数据
     * @param array $params
     * @param $where_price array 关联表查询
     * @param $where_array array 主表查询内容
     * @return mixed
     */
    public function getBackgroundImageQueryList(array $params, $where_price = [], $where_array = [])
    {

        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];
        $result = [];
        if (empty($where_price)) {
            $result = app('model_room_background')
                ->with([
                    'room_background_products_price' => function ($query) use ($where_price) {
                        $query->select('id', 'room_background_id', 'price', 'day')->where($where_price);
                    },
                ])
                ->where($where_array)
                ->orderBy('id', 'desc')
                ->paginate($perPage, ['*'], '', $page);
        } else {
            $result = app('model_room_background')
                ::whereHas('room_background_products_price', function ($query) use ($where_price) {
                    return $query->select('id', 'room_background_id', 'price', 'day')->where($where_price);
                })
                ->with([
                    'room_background_products_price' => function ($query) use ($where_price) {
                        $query->select('id', 'room_background_id', 'price', 'day')->where($where_price);
                    },
                ])
                ->where($where_array)
                ->orderBy('id', 'desc')
                ->paginate($perPage, ['*'], '', $page);
        }


        return $result;
    }

    /**
     * 理员后台查询配置数据
     * @param array $params
     * @param $where_price array 关联表查询
     * @param $where_array array 主表查询内容
     * @return mixed
     */
    public function getBackgroundImageBugLogList(array $params, $where_price = [], $where_array = [])
    {

        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $result = app('model_room_background_buy_log_view')
            ->where($where_array)
            ->where($where_price)
            ->orderBy('id', 'desc')
            ->paginate($perPage, ['*'], '', $page);

        return $result;
    }

    /**
     * 新增
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addSpecialRoom($param)
    {
        $addConfig = app('model_user_room_special')->create($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 删除
     */
    public function delSpecialRoom($idArr = [])
    {
        $res = app('model_user_room_special')->whereIn("id", $idArr)->delete();

        if ($res) {
            return $res;
        }
        throw new BasicException(93044);
    }

    /**
     * 修改
     */
    public function saveSpecialRoom($where, $param)
    {
        $saveConfig = app('model_user_room_special')->where($where)->update($param);

        if ($saveConfig !== false) {
            return true;
        }
        throw new BasicException(93047);
    }

    /**
     * 管理员后台查询配置数据
     */
    public function getSpecialRoomQueryList(array $params)
    {
        $whereArr = [];

        $whereFunc = function ($query) use ($params) {
            if (!empty($params["keyword"])) {
                $query->where("t2.room_name", "like", "%" . $params["keyword"] . "%")
                    ->orWhere("t2.room_id", "=", $params["keyword"]);
            }
        };

        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $specialRoomModel = app('model_user_room_special');
        $userRoomModel = app('model_user_room');
        $userDataModel = app('model_user_data');


        $result = app('model_user_room_special')
            ->from($specialRoomModel->getTable() . " as t1")
            ->select([
                "t1.id",
                "t1.special_flag_big",
                "t1.special_flag_small",
                "t1.frame_big",
                "t1.frame_small",
                "t1.expired_time",
                "t2.room_name",
                "t2.room_id",
                "t3.nickname",
                "t3.user_code",
            ])
            ->leftJoin(DB::raw($userRoomModel->getTable() . " as t2"), "t1.room_id", "=", "t2.id")
            ->leftJoin(DB::raw($userDataModel->getTable() . " as t3"), "t2.user_id", "=", "t3.user_id")
            ->where($whereArr)->where($whereFunc)->orderBy('t1.id', 'desc')->paginate($perPage, ['*'], '', $page);

        foreach ($result as $item) {
            $item->expired_time = empty($item->expired_time) ? '' : date("Y-m-d H:i:s", $item->expired_time);
        }

        return $result;
    }

    /**
     * 获取房间列表
     * @param $param
     * @param int $page
     * @param int $perPage
     * @return \Laravel\Lumen\Application|mixed
     */
    public function roomList($param, $page = 1, $perPage = 10)
    {
        $time = CommonService::transTime($param['start_at'], $param['end_at']);

        $list = app('model_user_room')->whereBetween('add_time', [$time['start_at'], $time['end_at']]);

        if (!empty($param['type_id'])) {
            $list = $list->where('sys_type_id', $param['type_id']);
        }
        if (!empty($param['label_id'])) {
            $list = $list->where('label_id', $param['label_id']);
        }
        if ($param['status'] != -1) {
            $list = $list->where('state', $param['status']);
        }
        if ($param['ball_status'] != -1) {
            $list = $list->where('show_ball_game', $param['ball_status']);
        }
        if ($param['hot_model'] != -1) {
            $list = $list->where('hot_model', $param['hot_model']);
        }
        if ($param['is_hot'] != -1) {
            $list = $list->where('hot_sort', ">", 0);
        }
        if ($param['star_state'] != -1) {
            $list = $list->where('star_state', $param['star_state']);
        }

        if (!empty($param['search'])) {
            //按房间号,手机号和房间名查询
            $search = $param['search'];

            $user = app('model_user')->where('mobile', $search)->select('user_id')->where('deleted', 0)->first();
            $uid = isset($user->user_id) ? $user->user_id : 0;

            //or查询
            $list = $list->where(function ($query) use ($search, $uid) {
                $query->where('user_id', $uid)->orWhere('room_id', $search)->orWhere(
                    'room_name',
                    'like',
                    "%{$search}%"
                );
            });
        }

        $list = $list->select(
            'id',
            'room_id',
            'room_name',
            'user_id',
            'label_id',
            'type_id',
            'sys_type_id',
            'water_ratio',
            'hot_sort',
            'cover_picture',
            'bg_picture',
            'sound_effect_id',
            'wheat',
            'seal_time',
            'add_time',
            'show_ball_game',
            'star_state',
            'state',
            'admin_state',
            'user_show_num_limit'
        )
            ->withOnly('user_data', ['user_code', 'user_id'])->withOnly(
                'user',
                ['user_id', 'mobile']
            )->withOnly('room_label', ['id', 'label_name'])
            ->withOnly('sound_effect', ['id', 'name'])
            ->withOnly('room_type', ['room_type_name', 'id'])->withOnly(
                'room_type_user',
                ['id', 'room_type_name']
            )
            ->orderBy('id', 'desc')->paginate($perPage, ['*'], '', $page);

        foreach ($list as &$val) {
            $val->user_code = isset($val->user_data->user_code) ? $val->user_data->user_code : '';
            $val->mobile = isset($val->user->mobile) ? $val->user->mobile : '';
            $val->label_name = isset($val->room_label->label_name) ? $val->room_label->label_name : '';
            $val->add_time = !empty($val->add_time) ? date('Y-m-d H:i:s', $val->add_time) : '';
            $val->seal_time = !empty($val->seal_time) ? date('Y-m-d H:i:s', $val->seal_time) : '';
            $val->sys_type_name = !empty($val->room_type->room_type_name) ? $val->room_type->room_type_name : '';
            $val->user_type_name = !empty($val->room_type_user->room_type_name) ? $val->room_type_user->room_type_name : '';
            $val->sound_effect_name = !empty($val->sound_effect->name) ? $val->sound_effect->name : '';
            //unset相关字段
            unset($val->sound_effect);
            unset($val->type_id);
            unset($val->sys_type_id);
            unset($val->room_type_user);
            unset($val->room_type);
            unset($val->user);
            unset($val->user_data);
            unset($val->room_label);
            unset($val->user_id);
            unset($val->label_id);
        }

        return $list;
    }

    /**
     * 房间详情
     * @param $id
     * @return mixed
     */
    public function getRoomDetail($id)
    {
        $room = app('model_user_room')->where('id', $id)
            ->select(
                'room_id',
                'user_id',
                'sound_effect_id',
                'hot_sort',
                'hot_model',
                'room_name',
                'sys_type_id',
                'label_id',
                'type_id',
                'wheat',
                'playing',
                'greeting',
                'cover_picture',
                'bg_picture',
                'show_ball_game',
                'seal_time',
                'state',
                'admin_state',
                'star_state',
                'hot_model',
                'is_pretty',
                'is_boss_pit',
                'password',
                'user_show_num_limit'
            )->first();
        $room->seal_time = !empty($room->seal_time) ? date('Y-m-d H:i:s', $room->seal_time) : '';
        $room->mobile = $this->getMobile($room->user_id);
        $room['type'] = $this->getRoomTypeArr(2);
        $room['sys_type'] = $this->getRoomTypeArr(1);
        $room['room_label'] = $this->getRoomLabelArr(0);
        $room['room_sound_effect'] = $this->getRoomSoundEffect();
        $room['time'] = $this->getBanTime($id);

        return $room;
    }

    /**
     * 修改房间信息
     * @param $id
     * @param $param
     * @param $mobile
     * @param $user_id
     * @param $admin_id
     * @param $start_time
     * @param $remark
     * @return mixed
     */
    public function executeRoomUpdate($id, $param)
    {
        //有密码就修改，没有则不做任何动作
        if (isset($param['password'])) {
            if ($param['password']) {
                $param['password'] = CommonService::pwdHash($param['password']);
            } else {
                unset($param['password']);
            }
        }

        if (empty($param['cover_picture'])) {
            unset($param['cover_picture']);
        }
        if (empty($param['bg_picture'])) {
            unset($param['bg_picture']);
        }
        if (isset($param['is_pretty']) && $param['is_pretty'] == 1) {
            $recommend = app('model_room_recommend')->where('room_id', $param['room_id'])->first();
            if (empty($recommend)) {
                $room = app('model_user_room')
                    ->with('user_data')
                    ->where('id', $id)
                    ->first();
                app('model_room_recommend')
                    ->create([
                        'room_id'    => $param['room_id'],
                        'user_code'  => $room->user_data->user_code ?? 0,
                        'type'       => 1,
                        'recommend_type_id'  => $param['sys_type_id'] ?? 0,
                        'start_time' => time(),
                        'end_time'   => strtotime('+2 week')
                    ]);
            }
        }

        // 隐藏房间修改
        if(isset($param['admin_state']) && !$param['admin_state'] && $param['admin_state'] == 0) {
            $param['state'] = 0;
        } else if (isset($param['admin_state']) && $param['admin_state'] == 1) {
            $param['state'] = 1;
        }

        DB::connection("mysql")->transaction(function () use ($id, $param) {
            DB::connection("mysql")->statement("SET names 'utf8mb4'");

            $room = app('model_user_room')->where('id', $id)->first();
            if (isset($param['room_name']) && $param['room_name'] != $room->room_name) {
                $data = [
                    'room_id'     => $room->id,
                    'change_from' => $room->room_name,
                    'change_to'   => $param['room_name'],
                    'type'        => 2, //1房间编号,2房间名称
                    'user_id'     => $room->user_id,
                    'admin_id'    => app("request")->admin_id,
                    'add_time'    => time(),
                ];
                app('model_room_change')->create($data);
            }

            if (isset($param['room_id']) && $param['room_id'] != $room->room_id) {
                // 房间code是否存在
                $roomExist = app('model_user_room')->select('id')->where('room_id', $param['room_id'])->where('id', '<>', $param['id'])->first();
                if ($roomExist) {
                    throw new BasicException(0, '房间号重复');
                }

                $data = [
                    'room_id'     => $room->id,
                    'change_from' => $room->room_id,
                    'change_to'   => $param['room_id'],
                    'type'        => 1,
                    'user_id'     => $room->user_id,
                    'admin_id'    => app("request")->admin_id,
                    'add_time'    => time(),
                ];
                app('model_room_change')->create($data);
            }

            $res = app('model_user_room')->where('id', $id)->update($param);
            if ($res) {
                Redis::del("sys_room_list");
                Redis::del(sprintf(RedisKeyEnum::ROOM_INFO, $room->id));

                if (isset($param['sys_type_id']) && $param['sys_type_id'] != $room->sys_type_id) {
                    //广播房间变更信息
                    //                    $data = [
                    //                        'room_id' => $room->id,
                    //                        'sys_type_id' => RoomEnum::clientRoomType($param['sys_type_id']),
                    //                        'old_sys_type_id' => RoomEnum::clientRoomType($room->sys_type_id),
                    //                    ];
                    //                    (new PushService())->roomTypeChange($data);

                    $old_key = sprintf(RedisKeyEnum::TYPE_ROOM_POPULARITY, $room->sys_type_id);
                    $new_key = sprintf(RedisKeyEnum::TYPE_ROOM_POPULARITY, $param['sys_type_id']);
                    $old_room_popularity = $this->getRoomPopularity($room->id);
                    app('redis')->zrem($old_key, $room->id);
                    $old_room_popularity = empty($old_room_popularity) ? 0 : $old_room_popularity;
                    app('redis')->zadd($new_key, $old_room_popularity, $room->id);
                    //兼容随心试听
                    $newSysTypeId = $param['sys_type_id'];
                    $oldSysTypeId  = $room->sys_type_id;
                    if (!empty($room['voice_introduction'])) {
                        if ($newSysTypeId == 18) {  //          女生
                            $userSex = 1;
                            $deleteUserSex = $userSex == 1 ? 2 : 1;
                            $sexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $userSex;
                            $deleteSexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $deleteUserSex;
                            app('redis')->zadd($sexKey, $old_room_popularity, $room->id);
                            app('redis')->zrem($deleteSexKey, $room->id);
                        } elseif ($newSysTypeId == 30) {  //          男生
                            $userSex = 2;
                            $deleteUserSex = $userSex == 1 ? 2 : 1;
                            $sexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $userSex;
                            $deleteSexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $deleteUserSex;
                            app('redis')->zadd($sexKey, $old_room_popularity, $room->id);
                            app('redis')->zrem($deleteSexKey, $room->id);
                        }
                    }

                    if ($oldSysTypeId == 18) {  //          女生
                        $userSex = 1;
                        $deleteSexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $userSex;
                        app('redis')->zrem($deleteSexKey, $room->id);
                    } elseif ($oldSysTypeId == 30) {  //          男生
                        $userSex = 2;
                        $deleteSexKey = RedisKeyEnum::ROOM_POPULARITY_SEX . $userSex;
                        app('redis')->zrem($deleteSexKey, $room->id);
                    }
                }
                // if(isset($param['state']) && !$param['state']){ //隐藏房间需要删除对应类型房间的人气
                //     $popularity_key = RedisKeyEnum::ALL_ROOM_POPULARITY;
                //     $old_key = sprintf(RedisKeyEnum::TYPE_ROOM_POPULARITY, $room->sys_type_id);
                //     app('redis')->zrem($old_key, $room->id);
                //     app('redis')->zrem($popularity_key, $room->id);
                // }

                //如果系统分类从其它类型改为相亲房，在room_pit增加10号麦位，反之则删除--
                /*if (isset($param['sys_type_id']) && $room->sys_type_id != RoomEnum::ROOM_TYPE_BLIND_DATE && $param['sys_type_id'] == RoomEnum::ROOM_TYPE_BLIND_DATE) {
                    app('model_room_pit')->insert([
                        'room_id' => $room->id,
                        'user_id' => $room->user_id,
                        'pit_number' => 10,
                    ]);
                }
                if (isset($param['sys_type_id']) && $room->sys_type_id == RoomEnum::ROOM_TYPE_BLIND_DATE && $param['sys_type_id'] != RoomEnum::ROOM_TYPE_BLIND_DATE) {
                    app('model_room_pit')
                        ->where('room_id', $room->id)
                        ->where('pit_number', 10)
                        ->delete();
                }*/

                //如果系统分类从其它类型改为拍卖房，或从拍卖房改为其它类型，上报到api项目接口
                if (isset($param['sys_type_id'])) {
                    if ($room->sys_type_id == RoomEnum::ROOM_TYPE_PM || $param['sys_type_id'] == RoomEnum::ROOM_TYPE_PM || $param['sys_type_id'] == RoomEnum::ROOM_TYPE_GAME) {
                        $this->isCurl = 1;
                        $this->orgSysTypeId = $room->sys_type_id;
                    }
                }

                //修改房间类型也需要关掉PK中的数据
                if (isset($param['sys_type_id']) && $param['sys_type_id'] != $room->sys_type_id) {
                    try {
                        app('repo_cross_room_pk')->abnormaHandle($room->id, CrossRoomPkEnum::ABNORMAL_SWITCH);
                    } catch (\Exception $exception) {
                        \Log::info('PK房出现错误了:'.$exception->getMessage());
                    }
                }
            }
        }, 5);
        if ($this->isCurl) {
            $url = env('ICE_API') . CurlReportUrlEnum::SWITCH_ROOM_MODULE;
            $reportData = [
                'room_id' => $id,
                'to_sys_type_id' => $param['sys_type_id'],
                'org_sys_type_id' => $this->orgSysTypeId,
            ];
            CurlService::curl_post($url, $reportData);
        }

        return true;
    }

    protected $isCurl;
    protected $orgSysTypeId;

    public function getRoomPopularity($roomId)
    {
        $redis = app('redis');
        $fixedRedisKey = RedisKeyEnum::ROOM_POPULARITY_FIXED . $roomId;
        $flowRedisKey = RedisKeyEnum::ROOM_POPULARITY_FLOW . $roomId;
        $fixedPopularity = $redis->get($fixedRedisKey);
        $flowPopularity = $redis->get($flowRedisKey);
        if ($fixedPopularity < 0) {
            $fixedPopularity = 0;
        }
        $fixedPopularity = $fixedPopularity <= 0 ? 0 : $fixedPopularity;
        if ($flowPopularity < 0) {
            $flowPopularity = 0;
        }
        $flowPopularity = $flowPopularity <= 0 ? 0 : $flowPopularity;


        return $fixedPopularity + $flowPopularity;
    }

    /**
     * 房间详情
     * @param $id
     * @param $param
     * @return mixed
     */
    public function executeRoomRateSet($id, $param)
    {
        app('model_user_room')->where('id', $id)->update($param);

        return true;
    }

    /**
     * 房间删除
     * @param $id
     * @return mixed
     */
    public function executeRoomDelete($idsArr)
    {
        DB::connection("mysql")->transaction(function () use ($idsArr) {
            app('model_room_favorite')->whereIn('room_id', $idsArr)->delete(); //删除收藏
            app('model_room_banned')->whereIn('room_id', $idsArr)->delete();
            app('model_room_blacklist')->whereIn('room_id', $idsArr)->delete();
            app('model_room_cardiac')->whereIn('room_id', $idsArr)->delete();
            app('model_room_change')->whereIn('room_id', $idsArr)->delete();
            app('model_room_charm')->whereIn('room_id', $idsArr)->delete();
            app('model_room_forbid')->whereIn('room_id', $idsArr)->delete();
            app('model_room_join_time')->whereIn('room_id', $idsArr)->delete();
            app('model_room_lock_log')->whereIn('room_id', $idsArr)->delete();
            app('model_room_report')->whereIn('room_id', $idsArr)->delete();
            app('model_room_seal')->whereIn('room_id', $idsArr)->delete();
            app('model_user_room')->whereIn('id', $idsArr)->delete();
            app('model_user_room_online')->whereIn('room_id', $idsArr)->delete();
        }, 5);

        return true;
    }

    /**
     * 获取分类数组
     * @param int $type 分类类别1房间分类2个人分类
     * @return array
     */
    public function getRoomTypeArr($type = 1)
    {
        $list = app('model_room_type');
        if (!empty($type)) {
            $result = $list->where('type', $type)->get();
        } else {
            $result = $list->where('id', ">", 0)->get();
        }
        $arr = [];

        foreach ($result as &$val) {
            $arr[$val->id] = $val->room_type_name;
        }

        return $arr;
    }

    /**
     * 获取音质
     * @return array
     */
    public function getRoomSoundEffect()
    {
        $list = app('model_room_sound_effect')->get();
        $arr = [];

        foreach ($list as &$val) {
            $arr[$val->id] = $val->name . '(' . $val->info . ')';
        }

        return $arr;
    }

    public function getMobile($user_id)
    {
        return app('model_user')->where('user_id', $user_id)->pluck('mobile')->where('deleted', 0)->first();
    }

    /**
     * 获取标签数组
     * @param int $type 分类类别1房间标签2个人标签
     * @return array
     */
    public function getRoomLabelArr($type = 1)
    {
        $list = app('model_room_label');
        if (!empty($type)) {
            $result = $list->where('type', $type)->get();
        } else {
            $result = $list->where('id', ">", 0)->get();
        }
        $arr = [];

        foreach ($result as &$val) {
            $arr[$val->id] = $val->label_name;
        }

        return $arr;
    }


    /**
     * 获取房间封禁列表
     * @param $param
     * @param int $page
     * @param int $perPage
     * @return \Laravel\Lumen\Application|mixed
     */
    public function roomBanList($param, $page = 1, $perPage = 10)
    {
        $list = app('model_room_seal');

        if (!empty($param['search'])) {
            $room = app('model_user_room')->where('room_id', $param['search'])->select('id')->first();
            $id = isset($room->id) ? $room->id : -1;
            $list = $list->where('room_id', $id);
        }

        $list = $list->withOnly('user_room', ['id', 'room_id', 'room_name'])->orderBy('id', 'desc')->paginate(
            $perPage,
            ['*'],
            '',
            $page
        );

        foreach ($list as &$val) {
            unset($val->room_id);
            $val->room_id = isset($val->user_room->room_id) ? $val->user_room->room_id : '';
            $val->room_name = isset($val->user_room->room_name) ? $val->user_room->room_name : '';
            $val->seal_time = date('Y-m-d H:i:s', $val->seal_time);
            unset($val->user_room);
        }

        return $list;
    }

    public function getBanTime($room_id)
    {
        $data = app('model_room_seal')->where('room_id', $room_id)->select(
            'start_time',
            'seal_time',
            'remark'
        )->orderBy('id', 'desc')->first();
        if (empty($data)) {
            return new \stdClass();
        }
        $data->start_time = !empty($data->start_time) ? date('Y-m-d H:i:s', $data->start_time) : '';
        $data->seal_time = !empty($data->seal_time) ? date('Y-m-d H:i:s', $data->seal_time) : '';

        return $data;
    }

    /**
     * 房间封禁
     * @param $room_id
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addRoomBan($room_id, $param)
    {
        $param['room_id'] = $room_id;
        $res = app('model_room_seal')->create($param);
        app('model_user_room')->where('id', $room_id)->update(['seal_time' => $param['seal_time']]);
        if ($res) {
            Redis::del(sprintf(RedisKeyEnum::ROOM_INFO, $room_id));
//            $url = env('REPORT_URL') . '/' . "service/room";
//            CurlService::curl_post($url, ['room_id' => $room_id]);
            //跨房PK,如果被封禁的用户是主持,并且正在PK中,那么直接发送PK异常的推送
            try {
                app('repo_cross_room_pk')->abnormaHandle($room_id, CrossRoomPkEnum::ABNORMAL_END);

            } catch (\Exception $exception) {
                \Log::info('PK房出现错误了:'.$exception->getMessage());
            }
            return true;
        }

        throw new BasicException(90010);
    }

    /**
     * 房间解封
     * @param $id
     * @return bool
     * @throws BasicException
     */
    public function executeRoomUnlock($id)
    {
        $res = app('model_user_room')->where('id', $id)->update(['seal_time' => 0]);
        if ($res !== false) {
            Redis::del(sprintf(RedisKeyEnum::ROOM_INFO, $id));
            return true;
        }

        throw new BasicException(90021);
    }

    /**
     * 删除封禁记录
     * @param $id
     * @return bool
     * @throws BasicException
     */
    public function roomBanlistDelete($idArr)
    {
        $res = app('model_room_seal')->whereIn('id', $idArr)->delete();

        if ($res) {
            return true;
        }

        throw new BasicException(90010);
    }

    /**
     * 锁房记录列表
     */
    public function roomLockList($params)
    {
        $whereArr = [];
        if (!empty($params["room_id"])) {
            $whereArr[] = ["t2.room_id", "=", $params["room_id"]];
        }

        if (!empty($params["state"])) {
            $whereArr[] = ["t1.state", "=", $params["state"]];
        }

        if (!empty($params["lock_time"])) {
            $whereArr[] = ["t1.lock_time", ">=", strtotime($params["lock_time"])];
            $whereArr[] = ["t1.lock_time", "<=", strtotime($params["lock_time"]) + 86399];
        }

        if (!empty($params["unlock_time"])) {
            $whereArr[] = ["t1.unlock_time", ">=", strtotime($params["unlock_time"])];
            $whereArr[] = ["t1.unlock_time", "<=", strtotime($params["unlock_time"]) + 86399];
        }

        if (!empty($params["room_name"])) {
            $whereArr[] = ["t2.room_name", "like", "%" . $params["room_name"] . "%"];
        }

        if (!empty($params["user_code"])) {
            $whereArr[] = ["t3.user_code", "=", $params["user_code"]];
        }

        if (!empty($params["nickname"])) {
            $whereArr[] = ["t3.nickname", "like", "%" . $params["nickname"] . "%"];
        }

        $whereFunc = function ($query) use ($params) {
        };

        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $lockLogModel = app('model_room_lock_log');
        $userRoomModel = app('model_user_room');
        $userDataModel = app('model_user_data');


        $result = app('model_room_lock_log')
            ->from($lockLogModel->getTable() . " as t1")
            ->select([
                "t1.*",
                "t2.room_name",
                "t2.room_id",
                "t3.user_code",
                "t3.nickname",
                "t3.head_picture",
            ])
            ->leftJoin(DB::raw($userRoomModel->getTable() . " as t2"), "t1.room_id", "=", "t2.id")
            ->leftJoin(DB::raw($userDataModel->getTable() . " as t3"), "t1.user_id", "=", "t3.user_id")
            ->where($whereArr)->where($whereFunc)->orderBy('t1.id', 'desc')->paginate($perPage, ['*'], '', $page);

        foreach ($result as $item) {
            $item->lock_delay_time = $item->state == 2 ? $item->unlock_time - $item->lock_time : 0;
            $item->lock_time = empty($item->lock_time) ? '' : date("Y-m-d H:i:s", $item->lock_time);
            $item->unlock_time = empty($item->unlock_time) ? '' : date("Y-m-d H:i:s", $item->unlock_time);
        }

        return $result;
    }

    /**
     * 房间修改记录列表
     */
    public function roomUpdateRecordList($params)
    {
        $whereArr = [];

        if (!empty($params['room_id'])) {
            $rmId = app('model_user_room')->where('room_id', $params['room_id'])->value('id');
            if ($rmId) {
                $whereArr[] = ["room_id", "=", $rmId];
            } else {
                $whereArr[] = ["room_id", "=", -1];
            }
        }

        if (!empty($params["room_name"])) {
            $rmId = app('model_user_room')->where('room_name', $params['room_name'])->value('id');
            if ($rmId) {
                $whereArr[] = ["room_id", "=", $rmId];
            } else {
                $whereArr[] = ["room_id", "=", -1];
            }
        }

        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $result = app('model_room_change')
            ->where($whereArr)->orderBy('id', 'desc')->paginate($perPage);

        foreach ($result as &$v) {
            $v->add_time = empty($v->add_time) ? '' : date("Y-m-d H:i:s", $v->add_time);
            $v->operator = '';
            if ($v->admin_id > 0) {
                $adminName = app('model_admin')->where('admin_id', $v->admin_id)->value('admin_name');
                if ($adminName) $v->operator = $adminName;
            } else if ($v->user_id > 0) {
                $nickname = app('model_user_data')->where('user_id', $v->user_id)->value('nickname');
                if ($nickname) $v->operator = $nickname;
            }
            $room = app('model_user_room')->select('room_id', 'room_name')->where('id', $v->room_id)->first();
            if ($room) {
                $v->room_id = $room->room_id;
                $v->room_name = $room->room_name;
            } else {
                $v->room_id = '';
                $v->room_name = '';
            }
        }

        return $result;
    }

    /**
     * 分类列表
     * @param int $type
     * @param int $page
     * @param int $perPage
     * @return mixed
     */
    public function getRoomTypeList($type, $page = 1, $perPage = 10)
    {
        $list = app('model_room_type')->where('type', $type)
            ->orderBy('sort', 'desc')->paginate($perPage, ['*'], '', $page);
        foreach ($list as &$val) {
            $val->type_name = isset($val->room_type_name) ? $val->room_type_name : '';
            unset($val->room_type_name);
        }

        return $list;
    }

    /**
     * 新增
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addRoomType($param)
    {
        $addConfig = app('model_room_type')->create($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 删除
     */
    public function delRoomType($idArr = [])
    {
        $res = app('model_room_type')->whereIn("id", $idArr)->delete();

        if ($res) {
            return $res;
        }
        throw new BasicException(93044);
    }

    /**
     * 修改
     */
    public function saveRoomType($where, $param)
    {
        $saveConfig = app('model_room_type')->where($where)->update($param);

        //        if ($saveConfig) return $saveConfig;
        //        throw new BasicException(93047);
    }

    /**
     * 标签列表
     * @param int $type
     * @param int $page
     * @param int $perPage
     * @return mixed
     */
    public function getRoomLabelList($type, $page = 1, $perPage = 10)
    {
        $list = app('model_room_label')->where('type', $type)
            ->orderBy('id', 'desc')->paginate($perPage, ['*'], '', $page);
        foreach ($list as &$val) {
            $val->type_name = isset($val->label_name) ? $val->label_name : '';
            unset($val->label_name);
        }

        return $list;
    }

    /**
     * 新增
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addRoomLabel($param)
    {
        $addConfig = app('model_room_label')->create($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 删除
     */
    public function delRoomLabel($idArr = [])
    {
        $res = app('model_room_label')->whereIn("id", $idArr)->delete();

        if ($res) {
            return $res;
        }
        throw new BasicException(93044);
    }

    /**
     * 修改
     */
    public function saveRoomLabel($where, $param)
    {
        $saveConfig = app('model_room_label')->where($where)->update($param);

        if ($saveConfig !== false) {
            return true;
        }
        throw new BasicException(93047);
    }

    /**
     * 踢人记录列表
     * @param $param
     * @param int $page
     * @param int $perPage
     * @return mixed
     */
    public function roomKickoutList($param, $page = 1, $perPage = 10)
    {
        $list = app('model_room_kickout');

        if (isset($param['start_at']) && isset($param['end_at'])) {
            $time = CommonService::transTime($param['start_at'], $param['end_at']);
            $list = $list->whereBetween('add_time', $time);
        }

        if (!empty($param['user_id'])) {
            $search = $param['user_id'];
            //踢人者ID
            $list = $list->where(function ($query) use ($search) {
                $query->WhereHas('user_data', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_data')->where('user_code', $search);
                });
            });
        } else {
            $list = $list->with('user_data:user_id,user_code,nickname');
        }

        if (!empty($param['nickname'])) {
            $search = $param['nickname'];
            //踢人者昵称
            $list = $list->where(function ($query) use ($search) {
                $query->WhereHas('user_data', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_data')->where('nickname', "like", "%" . $search . "%");
                });
            });
        }

        if (!empty($param['user_id_out'])) {
            $search = $param['user_id_out'];
            //踢人者ID
            $list = $list->where(function ($query) use ($search) {
                $query->WhereHas('user_data2', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_data')->where('user_code', $search);
                });
            });
        } else {
            $list = $list->with('user_data2:user_id,user_code,nickname');
        }

        if (!empty($param['nickname_out'])) {
            $search = $param['nickname_out'];
            //踢人者昵称
            $list = $list->where(function ($query) use ($search) {
                $query->WhereHas('user_data2', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_data')->where('nickname', "like", "%" . $search . "%");
                });
            });
        }

        if (!empty($param['room_id'])) {
            $search = $param['room_id']; //房间ID
            $list = $list->where(function ($query) use ($search) {
                $query->whereHas('user_room', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_room')->where('room_id', $search);
                });
            });
        } elseif (!empty($param['room_name'])) {
            //dd($param['room_name']);
            $search = $param['room_name']; //房间名
            $list = $list->where(function ($query) use ($search) {
                $query->whereHas('user_room', function ($query) use ($search) {
                    $query->from(env('DB_DATABASE') . '.ln_user_room')->where('room_name', "like", "%" . $search . "%");
                });
            });
        } else {
            $list = $list->with('user_room:id,room_id,user_id,room_name');
        }

        $list = $list->orderBy('id', 'desc')->paginate($perPage, ['*'], '', $page);

        foreach ($list as &$val) {
            $val->room_id = isset($val->user_room->room_id) ? $val->user_room->room_id : ''; //房间编号
            $val->room_name = isset($val->user_room->room_name) ? $val->user_room->room_name : '';
            $val->user_id = isset($val->user_data->user_code) ? $val->user_data->user_code : '';
            $val->nickname = isset($val->user_data->nickname) ? $val->user_data->nickname : '';
            $val->user_id_out = isset($val->user_data2->user_code) ? $val->user_data2->user_code : '';
            $val->nickname_out = isset($val->user_data2->nickname) ? $val->user_data2->nickname : '';
            $val->add_time = !empty($val->add_time) ? date('Y-m-d H:i:s', $val->add_time) : '';
            unset($val->user_data2);
            unset($val->user_data);
            unset($val->user_room);
        }

        return $list;
    }

    /**
     * 房间总流水
     */
    public function getRoomTotalIncome(array $params)
    {
        $whereArr = [];
        if (!empty($params["id"])) {
            $whereArr[] = ["room_id", "=", $params["id"]];
        }

        if (!empty($params["start_time"])) {
            $whereArr[] = ["add_time", ">=", strtotime($params["start_time"])];
        }

        if (!empty($params["end_time"])) {
            $whereArr[] = ["add_time", "<=", strtotime($params["end_time"])];
        }
        $result = app("model_give_gift")->where($whereArr)->sum("total_price");

        return $result;
    }

    /**
     * 管理员后台查询配置数据
     */
    public function getRoomIncomeQueryList(array $params)
    {
        $start_time = isset($params['start_time']) ? strtotime($params['start_time']) : 0;
        $end_time = isset($params['end_time']) ? strtotime($params['end_time'] . " 23:59:59") : 0;
        $room_id = $params['id'];

        //用户总充值
        $whereFunc = function ($query) use ($start_time, $end_time, $room_id) {
            if ($start_time) {
                $query->whereRaw(DB::raw("add_time >= {$start_time}"));
            }
            if ($end_time) {
                $query->whereRaw(DB::raw("add_time <= {$end_time}"));
            }

            $query->whereRaw(DB::raw("room_id = {$room_id}"));
        };

        $page = empty($params['page']) ? 1 : $params['page'];
        $perPage = empty($params['perPage']) ? 10 : $params['perPage'];

        $subQuery = app('model_give_gift')
            ->select(
                DB::raw("sum(total_price) as number"),
                DB::raw("from_UNIXTIME(`add_time`,'%Y-%m-%d') as time")
            )
            ->groupBy(DB::raw("from_UNIXTIME(`add_time`,'%Y-%m-%d')"))
            ->where($whereFunc);

        $result = DB::connection('mysql')->table(DB::raw("({$subQuery->toSql()}) as t1"))
            ->setBindings(["1", "2", "3", "4", "5", "6"])
            ->orderBy('t1.time', 'desc')
            ->paginate($perPage, ['*'], '', $page);

        return $result;
    }

    /**
     * 根据room_id获取单个房间的人气值
     * @param int $room_id
     * @return int|number
     */
    public function getPopularityByRoomId($room_id = 0)
    {
        $roomPopularity = 0;
        $time = time();
        $pattern = 'popu:r:' . $room_id;  //非模糊匹配,准确搜索

        //查询符合条件的集合数组
        $keys_arr = Redis::zrangebyscore($pattern, $time, "+inf");

        if (!empty($keys_arr)) {
            $val_list = Redis::mget($keys_arr);  //查询不到返回false
            if ($val_list) {
                $roomPopularity = array_sum($val_list);
            }
        }

        return $roomPopularity;
    }

    /**
     * 赠送人气
     */
    public function sendPopularity($id, array $params)
    {
        $userRoom = app("model_user_room")->where("id", $id)->first();
        if (!$userRoom) {
            throw new BasicException(10001, "不合法的房间id！");
        }
        $popularity = $params['popularity'];
        $expireTime = strtotime($params['expire_time']);

        //开启事务存储room_id和popularity_value,暂不对异常处理
        Redis::multi();

        $time = time();

        $sign = 0;

        $type = 5;

        //命名构成room:p:$room_id.t.$type.u.$sign.d.time().rand()
        $key = uniqid('popu:p:' . $id . 't' . $type . 'u' . $sign . 'd' . $time, true);

        $endTime = $time + $expireTime;

        Redis::setex($key, $expireTime, $popularity);

        $roomSetKey = 'popu:r:' . $id;

        Redis::zadd($roomSetKey, $endTime, $key);

        //记录日志
        $data = [
            'room_id'     => $id,
            'popularity'  => $popularity,
            'type'        => 1,
            'start_at'    => $time,
            'end_at'      => $endTime,
            'expire_time' => $expireTime,
            'sign'        => $sign,
        ];

        $log_key = uniqid("popu:log:" . date('YmdHis', time()) . 'r' . $id . $type, true);
        Redis::set($log_key, json_encode($data));

        $status = Redis::exec();

        if (!$status) {
            Redis::discard();
        }   //异常回滚

        $roomPopularity = $this->getPopularityByRoomId($id);

        //发送消息
        $mqtt = app("repo_mqtt");
        $mqtt->setRoom($id);
        $mqtt->updatePopularity($roomPopularity);

        return true;
    }

    public function getRoomSysTypeId($room_id)
    {
        $result = app('model_user_room')->where('id', $room_id)->select(['sys_type_id', 'type_id'])->first();
        if (!$result) {
            return 0;
        }

        return $result->sys_type_id > 0 ? $result->sys_type_id : $result->type_id;
    }

    /**
     * 新增
     * @param $param
     * @return bool
     * @throws BasicException
     */
    public function addRoomRecommend($param)
    {
        $param['start_time'] = strtotime($param['start_time']);
        $param['end_time'] = strtotime($param['end_time']);
        $param['type'] = 1;
        $info = $this->getRecommendDetail(['room_id' => $param['room_id']]);
        if (!empty($info)) {
            throw new BasicException(0, '数据已存在，无须重复添加');
        }
        // 房间分类
        $recommend_type_id = app('model_user_room')->where('room_id', $param['room_id'])->pluck('sys_type_id')->toArray();
        $param['recommend_type_id'] = $recommend_type_id[0];
        $addConfig = app('model_room_recommend')->create($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 获取推荐房详情
     */
    public function getRecommendDetail($where)
    {
        $info = app('model_room_recommend')
            ->with(['user_data' => function ($query) {
                $query->select('user_code', 'nickname');
            }])
            ->with(['user_room' => function ($query) {
                $query->select('room_id', 'id');
            }])
            ->where($where)->first();
        if (!empty($info)) {
            $info = $info->toArray();
            $ids = $info->user_room->id ?? 0;
            $popularity = $this->getRoomsPopularity([$ids]);
            $info['popularity'] = $popularity[0] ?? 0;
            $info['start_time'] = date('Y-m-d H:i:s', $info['start_time']);
            $info['end_time'] = date('Y-m-d H:i:s', $info['end_time']);
        } else {
            $info = [];
        }

        return $info;
    }

    /**
     * 修改房间推荐
     */
    public function updateRecommend($where, $param)
    {
        $param['start_time'] = strtotime($param['start_time']);
        $param['end_time'] = strtotime($param['end_time']);
        $info = $this->getRecommendDetail(['id' => $param['id']]);
        if (empty($info)) {
            throw new BasicException(0, '数据不存在');
        }
        $addConfig = app('model_room_recommend')->where($where)->update($param);

        if ($addConfig) {
            return $addConfig;
        }
        throw new BasicException(93045);
    }

    /**
     * 推荐列表
     */
    public function recommendNewLists($params)
    {
        $perPage = $params['perPage'];
        $page = $params['page'];
        $where = [];
        if (!empty($params['room_id'])) {
            $where['room_id'] = $params['room_id'];
        }
        if (!empty($params['user_code'])) {
            $where['user_code'] = $params['user_code'];
        }
        $where['type'] = $params['type'];
        $lists = app('model_room_recommend')
            ->where($where)
            ->with(['user_data' => function ($query) use ($params) {
                $query->select('user_code', 'nickname');
            }])
            ->with(['user_room' => function ($query) {
                $query->select('room_id', 'id');
            }])
            ->orderBy('id', 'desc');
        if (!empty($params['start_time'])) {
            $lists->where('start_time', '>=', $params['start_time']);
        }
        if (!empty($params['end_time'])) {
            $lists->where('end_time', '<=', $params['end_time']);
        }
        if (!empty($params['nickname'])) {
            $nickname = $params['nickname'];
            $lists->whereHas('user_data', function ($query) use ($nickname) {
                return $query->select('user_code', 'nickname')->where('nickname', 'like', '%' . $nickname . '%');
            });
        }
        $lists->with(['user_data' => function ($query) use ($params) {
            $query->select('user_code', 'nickname');
        }]);
        $lists = $lists->paginate($perPage, ['*'], '', $page);
        // 获取人气
        $ids = [];
        foreach ($lists as $k => $v) {
            if (isset($v['user_room']['id'])) {
                array_push($ids, $v['user_room']['id']);
            }
            $lists[$k]['start_time'] = date('Y-m-d H:i:s', $v['start_time']);
            $lists[$k]['end_time'] = date('Y-m-d H:i:s', $v['end_time']);
        }
        $popularityArr = $this->getRoomsPopularity($ids);
        foreach ($lists as $key => $val) {
            $roomId = $val['user_room']['id'] ?? 0;
            $lists[$key]['popularity'] = $popularityArr[$roomId] ?? 0;
        }
        if ($params['sort_type'] == 2 && !empty($lists)) {
            $lists = $lists->toArray();
            array_multisort(array_column($lists['data'], 'popularity'), SORT_DESC, $lists['data']);
        }
        return $lists;
    }

    // 获取房间人气
    public function getRoomsPopularity($roomIds)
    {
        if (empty($roomIds)) {
            return [];
        }
        $fixedRedisKeys = $flowRedisKeys = [];
        foreach ($roomIds as $k => $roomId) {
            $roomIds[$k] = [
                'key' => $roomId,
            ];
            $fixedRedisKeys[$k] = RedisKeyEnum::ROOM_POPULARITY_FIXED . $roomId;
            $flowRedisKeys[$k] = RedisKeyEnum::ROOM_POPULARITY_FLOW . $roomId;
        }
        $fixedPopularityArr = app('redis')->mGet($fixedRedisKeys);
        $flowPopularityArr = app('redis')->mGet($flowRedisKeys);
        $return = [];
        foreach ($roomIds as $k => $v) {
            $fixedPopularity = isset($fixedPopularityArr[$k]) ? $fixedPopularityArr[$k] : 0;
            $flowPopularity = isset($flowPopularityArr[$k]) ? $flowPopularityArr[$k] : 0;
            $fixedPopularity = $fixedPopularity <= 0 ? 0 : (int)$fixedPopularity;
            $flowPopularity = $flowPopularity <= 0 ? 0 : (int)$flowPopularity;
            $return[$v['key']] = $flowPopularity + $fixedPopularity;
        }

        return $return;
    }

    /**
     * 删除推荐房间
     */
    public function delRecommend($idArr)
    {
        $res = app('model_room_recommend')->where("id", $idArr)->delete();

        if ($res) {
            return $res;
        }
        throw new BasicException(93044);
    }

    /**
     * 更新数据信息
     * @param $ids string 数据信息集合
     */
    public function updateRecommendType($ids)
    {
        // 更新所有的数据信息
        app('model_room_type')->where('is_delete', 0)->update(['is_recommend' => 0]);
        $ids = explode(',', $ids);
        $res = app('model_room_type')->whereIn('id', $ids)->update(['is_recommend' => 1]);
        return $res;
    }

    /**
     * 返回分类类型
     * @return mixed
     */
    public function getTypeLists()
    {
        return app('model_room_type')->where('is_delete', 0)->get()->toArray();
    }

    /**
     * 推荐列表
     * @param $params
     */
    public function recommendLists($params)
    {
        $perPage = $params['perPage'];
        $page = $params['page'];
        $where = [];
        // 获取推荐类目
        $type_list = app('model_room_type')
            ->where('is_delete', 0)
            ->where('is_recommend', 1)
            ->get()->toArray();
        $type_ids = array_column($type_list, 'id');
        $lists = app("model_user_room")
            ->whereIn('sys_type_id', $type_ids)
            ->with(['user_data' => function ($query) use ($params) {
                $query->select('user_code', 'nickname', 'user_id');
            }])
            ->with(['room_type' => function ($query) use ($params) {
                $query->select('id', 'room_type_name');
            }])
            ->select('id', 'room_id', 'user_id', 'room_name', 'sys_type_id')
            ->get()->toArray();
        // 获取人气
        $ids = [];
        foreach ($lists as $k => $v) {
            array_push($ids, $v['id']);
        }
        $popularityArr = $this->getRoomsPopularity($ids);
        foreach ($lists as $key => $val) {
            $lists[$key]['popularity'] = isset($popularityArr[$val['id']]) ? $popularityArr[$val['id']] : 0;
        }
        if (!empty($lists)) {
            array_multisort(array_column($lists, 'popularity'), SORT_DESC, $lists);
        }
        foreach ($lists as $key => $val) {
            $lists[$key]['id'] = $key + 1;
        }
        // 手动分页
        $start = ($page - 1) * $perPage;
        $final = array_slice($lists, $start, $perPage);
        $result['data'] = $final;
        $result['total'] = count($lists);
        return $result;
    }

    /**
     * 获取房间搜索类型
     */
    public function getRoomSearch($params)
    {
        $lists = app("model_user_room")
            ->where('room_id', $params)
            ->with(['user_data' => function ($query) {
                $query->select('user_code', 'nickname', 'user_id');
            }])
            ->with(['room_type' => function ($query) {
                $query->select('id', 'room_type_name');
            }])
            ->select('id', 'room_id', 'user_id', 'room_name', 'sys_type_id')
            ->first();
        return empty($lists) ? [] : $lists->toArray();
    }
}
